using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Xml.Linq;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Media;

namespace Pokemon
{
    class ZSpineSkeleton : Zombie
    {
         public ZSpineSkeleton(Game game, Blank owner, Vector2 position)
            : base(game, owner, position)
        {

        }


         /// <summary>
         /// Allows the game component to perform any initialization it needs to before starting
         /// to run.  This is where it can query for any required services and load content.
         /// </summary>
         public override void Initialize()
         {
             XDocument doc = XDocument.Load(@"Content/Textures/Zombies/ZSpineSkeleton/ZSpineSkeletonDef.xml");
             Texture2D texture2;
             Vector2 frameSize = Vector2.Zero;
             Vector2 centerPoint = Vector2.Zero;
             int numFrame;
             XName name = XName.Get(@"FrameWidth");
             if (doc.Document != null)
             {
                 var definitions = doc.Document.Descendants(name);
                 Int32 frameWidth = Int32.Parse((definitions.First()).Value);

                 name = XName.Get(@"FrameHeight");
                 definitions = doc.Document.Descendants(name);
                 Int32 frameHeight = Int32.Parse((definitions.First()).Value);
                 Size = new Vector2(frameWidth, frameHeight);

                 name = XName.Get("Damages");
                 definitions = doc.Document.Descendants(name);
                 Damage = Int32.Parse((definitions.First()).Value);

                 name = XName.Get("Healths");
                 definitions = doc.Document.Descendants(name);
                 _health = Int32.Parse((definitions.First()).Value);

                 name = XName.Get("Speed");
                 definitions = doc.Document.Descendants(name);
                 _speed = Int32.Parse((definitions.First()).Value);

                 name = XName.Get(@"Range");
                 definitions = doc.Document.Descendants(name);
                 _range = Int32.Parse(definitions.First().Value);

                 name = XName.Get(@"Definition");
                 definitions = doc.Document.Descendants(name);
                 foreach (var definition in definitions)
                 {
                     var xAttribute = definition.Attribute(@"SheetName");
                     texture2 = Game.Content.Load<Texture2D>(xAttribute.Value);
                     xAttribute = definition.Attribute(@"FrameWidth");

                     var width = Int32.Parse(xAttribute.Value);
                     xAttribute = definition.Attribute(@"FrameHeight");

                     var height = Int32.Parse(xAttribute.Value);
                     frameSize = new Vector2(width, height);
                     xAttribute = definition.Attribute(@"XCenterPoint");

                     var xCenterPoint = Int32.Parse(xAttribute.Value);
                     xAttribute = definition.Attribute(@"YCenterPoint");

                     var yCenterPoint = Int32.Parse(xAttribute.Value);

                     centerPoint = new Vector2(xCenterPoint, yCenterPoint);

                     xAttribute = definition.Attribute(@"NumFrame");
                     numFrame = Int32.Parse(xAttribute.Value);

                     xAttribute = definition.Attribute(@"Name");
                     var type = xAttribute.Value;

                     Sprite sprite = new Sprite(texture2, numFrame, frameSize, centerPoint, false);

                     switch (type)
                     {
                         case "Idle":
                             Textures[0] = sprite;
                             break;
                         case "Attack":
                             Textures[1] = sprite;
                             break;
                         case "Hit":
                             Textures[2] = sprite;
                             break;
                         case "Dead":
                             Textures[3] = sprite;
                             break;
                         case "Stand":
                             Textures[4] = sprite;
                             break;
                     } 
                 }
             }
             base.Initialize();
         }

         public override void TakeDamage(int damage, Color color)
         {
             _health -= damage;
             _Color = color;
             //if (_health <= 0)
             //{

             //}             
             //base.TakeDamage(damage, color);
         }
        
         public override void Update(GameTime gameTime)
         {

             _TimeSpan += gameTime.ElapsedGameTime;
             if (_TimeSpan.Milliseconds < 100)
                 return;
             if (_health <= 0 && _TimeSpan.Milliseconds < 100)
                 return;
             base.Update(gameTime);
             _TimeSpan = TimeSpan.Zero;
             _position.X -= _speed / 1000;             
             if (_health <= 0)
             {
                 if (_UnitState == UnitState.Dead)
                 {
                     if (Textures[GetUnitStateIndex()].FrameIndex >= 5)
                     {
                         CreateBoom();
                         ((GameplayScreen)(_owner.Owner.Owner)).UnitDestroy(this);                         
                         return;
                     }
                 }
                 else
                 {
                     Dead();
                 }
             }

             if (_enemy != null)
             {
                 if (Blank.GetDistance(GetCenterPoint(), _enemy.GetCenterPoint()) < _range)
                 {
                     if (_UnitState == UnitState.Idle)
                         Attack();
                     else
                         if (Textures[GetUnitStateIndex()].FrameIndex == 3)
                             _enemy.TakeDamage(Damage, Color.White);
                     _position.X += _speed / 1000;
                 }
                 else
                     if (_UnitState == UnitState.Attack)
                         Idle();
             }
             else
             {
                 if (_UnitState == UnitState.Attack)
                     Idle();
             }
             Textures[GetUnitStateIndex()].Update();
             //base.Update(gameTime);
         }
         /// <summary>
         /// Lay diem center cua zombie
         /// </summary>
         /// <returns></returns>
         public override Point GetCenterPoint()
         {
             int index = GetUnitStateIndex();
             return 
                 new Point((int)_position.X + /*(int)_frameSize[index].X - */(int)Textures[index].CenterPoint.X, 
                     (int)_position.Y + (int)Textures[index].CenterPoint.Y);
         }

         /// <summary>
         /// Huy doi tuong
         /// </summary>
         /// <param name="disposing"></param>

         protected override void Dispose(bool disposing)
         {
             GameScreen gc = Owner.Owner.Owner;
             if (gc is GameplayScreen)
                 ((GameplayScreen)gc).OnZombieDead();
             base.Dispose(disposing);
         }

         /// <summary>
         /// Ve spirte len man hinh
         /// </summary>
         /// <param name="gameTime"></param>
         public override void Draw(GameTime gameTime)
         {
             Rectangle rect = GetNextRect();
             SpriteBatch _SpriteBatch = (SpriteBatch)Game.Services.GetService(typeof(SpriteBatch));

             Vector2 ownerEndPoint = Vector2.Zero;
             if (_owner != null)
             {
                 ownerEndPoint = new Vector2(_owner.Position.X + _owner.Size.X, _owner.Position.Y + _owner.Size.Y);

                 Vector2 position = new Vector2(ownerEndPoint.X - _size.X, ownerEndPoint.Y - _size.Y);
                 int index = GetUnitStateIndex();
                 Textures[index].Draw(_SpriteBatch, new Vector2(_position.X, position.Y) + new Vector2(0, -12), 
                     rect, Color.White, 0, Vector2.Zero, 1.0f, SpriteEffects.None, 0);                 
             }
             base.Draw(gameTime);
         }


         /// <summary>
         /// Trang thai tan cong cua zombie
         /// </summary>
         public void Attack()
         {
             var prevIndex = GetUnitStateIndex();
             _UnitState = UnitState.Attack;
             var index = GetUnitStateIndex();
             Size = Textures[index].Size;
             float detY = Textures[prevIndex].Size.Y - Size.Y;
             float detX = Textures[prevIndex].Size.X - Size.X;
             Position = Position + new Vector2(detX, detY) + new Vector2(0, 15);
             _textures[prevIndex].Reset();
             _textures[index].Reset();
         }

         /// <summary>
         /// Trang thai di chuyen/dung yen cua zombie       
         /// </summary>
         public void Idle()
         {
             var prevIndex = GetUnitStateIndex();
             _UnitState = UnitState.Idle;
             var index = GetUnitStateIndex();
             Size = Textures[index].Size;
             float detY = Textures[prevIndex].Size.Y - Size.Y;
             float detX = Textures[prevIndex].Size.X - Size.X;
             Position = Position + new Vector2(detX, detY) - new Vector2(0, 15);
             _textures[prevIndex].Reset();
             _textures[index].Reset();
         }

         /// <summary>
         /// Trang thai zombie bi het mau va chet
         /// </summary>
         public void Dead()
         {
             var prevIndex = GetUnitStateIndex();
             _UnitState = UnitState.Dead;
             var index = GetUnitStateIndex();
             Size = Textures[index].Size;
             float detY = Textures[prevIndex].Size.Y - Size.Y;
             float detX = Textures[prevIndex].Size.X - Size.X;
             Position = Position + new Vector2(detX, detY) - new Vector2(0, 15);
             _textures[prevIndex].Reset();
             _textures[index].Reset();
         }
    }
}
